/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package abricots.game.state;

import abricots.MyLog;
import abricots.game.GameEnv;
import abricots.game.GameUtils;
import abricots.net.GameClient;
import abricots.net.common.GameMessage;
import abricots.net.GameServer;
import abricots.net.common.NetUtils.GameClientListener;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.minlog.Log;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

/**
 *
 * @author charly
 */
public class ConnectingState extends BasicGameState implements GameClientListener {
   private final MyLog log = new MyLog(getClass().getSimpleName(), Log.LEVEL_DEBUG);
   private ConnectingStateMessageDispatcher dispatcher;
   private GameEnv env;
   private GameClient client;
   private StateBasedGame game;
   private String output = "HAHA";
   private GameMessage lasMessage;
   private boolean synced;
   private boolean syncing;

   public ConnectingState(GameEnv env, GameClient client) {
      this.env = env;
      dispatcher = new ConnectingStateMessageDispatcher(env, this);
      this.client = client;
   }

   @Override
   public int getID() {
      return GameUtils.STATE_ID_CONNECTING;
   }

   @Override
   public void init(GameContainer container, StateBasedGame game) throws SlickException {
      this.game = game;
      client.startClient();
      log.debug("Started client");
   }

   @Override
   public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
      g.setColor(Color.yellow);
      g.drawString(output, 12, 13);
      g.setColor(Color.gray);
      if (lasMessage != null) {
         g.drawString(lasMessage.toString(), 12, 33);
      }
   }

   @Override
   public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
      if (syncing) {
         GameMessage.GameTimeSyncMessage message = new GameMessage.GameTimeSyncMessage();
         message.gameTime = env.getTimeManager().getGameTime();
         client.send(message);
      }
      if (synced) {
         game.enterState(GameUtils.STATE_ID_TEST);
      }
   }

   @Override
   public void keyPressed(int key, char c) {
      switch (key) {
         case Input.KEY_S:
            startServer();
            break;
         case Input.KEY_C:
            connect();
            break;
      }
   }

   private void startServer() {
      log.debug("Starting server");
      GameServer server = new GameServer();
      server.startServer();
      output = "Server started!";
   }

   private void connect() {
      log.debug("Starting client");
      output = "trying to connect..";
      client.connect();
   }

   @Override
   public void messageReceived(Object message, Connection connection) {
      log.trace("Message received: " + message.toString());
      dispatcher.dispatchMessage(message, connection);
      lasMessage = (GameMessage) message;
   }

   @Override
   public void connectionFailed() {
      output = "Connection failed";
   }

   @Override
   public void onConnection(Connection connection) {
      output = "Connected!";
      syncing = true;
   }

   @Override
   public void onDisConnection(Connection connection) {
      output = "Disconnected";
   }

   @Override
   public void enter(GameContainer container, StateBasedGame game) throws SlickException {
      super.enter(container, game);
      client.addListener(this);
      log.debug("entering");
   }

   @Override
   public void leave(GameContainer container, StateBasedGame game) throws SlickException {
      super.leave(container, game);
      client.removeListener(this);
      log.debug("leaving");
   }

   void setSynced(boolean b) {
      synced = b;
      log.trace("synced set to " + Boolean.toString(b));
   }
}
